/**
 * 微信支付公共类
 */
var apiConfig = require('../configs/appConfig');
var security = require('../providers/security');
var common = require('../helpers/common');
var request = require('request');

let prepaySign = function (appId,mchId,sub_appId,sub_mchId,nonce_str,body,out_trade_no,total_fee,spbill_create_ip,notify_url,trade_type,attach,openid) {
  var ret = {
    appid: appId,
    attach: attach,
    body: body,
    mch_id: mchId,
    nonce_str: nonce_str,
    notify_url: notify_url,
    out_trade_no: out_trade_no,
    spbill_create_ip: spbill_create_ip,
    sub_appid: sub_appId,
    sub_mch_id: sub_mchId,
    total_fee: total_fee,
    openid: openid,
    trade_type: trade_type,
    sub_openid: openid
  }
  var string = raw(ret);
  var key = apiConfig.wx.key;
  string = string + '&key=' + key;
  console.log(string);
  return security.md5(string).toUpperCase();
}


let wxSign = async (appId,pck,timstamp,nonceStr,signType) => {
  var ret = {
    appId: appId,
    nonceStr: nonceStr,
    timeStamp: timstamp,
    package: pck,
    signType: signType
  };
  var string = raw(ret);
  string = string + '&key=' + apiConfig.wx.key;
  return security.md5(string).toUpperCase();
}

let raw = function (args) {
  var keys = Object.keys(args);
  keys = keys.sort()
    var newArgs = {};
    keys.forEach(function (key) {
      newArgs[key] = args[key];
    });
    var string = '';
    for (var k in newArgs) {
      if (newArgs[k] != '') {
        string += '&' + k + '=' + newArgs[k];
      }
    }
    string = string.substr(1);
    return string;
}

let paysign = async (appId,nonce_str,pck,partnerid,prepayId,timeStamp) => {
  var ret = {
    appid: appId,
    noncestr: nonce_str,
    package: pck,
    partnerid: partnerid,
    prepayid: prepayId,
    timestamp: timeStamp
  }
  var string =  raw(ret);
  string = string + '&key=' + apiConfig.key;
  return security.md5(string).toUpperCase();
}

let parseBody = async (err,response,body,pf,orderNum) => {
  console.log("错误信息：" + JSON.stringify(response) + "|" + JSON.stringify(err));
  if(!err && response.statusCode == 200){
    var resJson = await common.xml2Json(body);
    console.log("解析xml: xml=> " + body + " | json=> " + resJson);
    if("SUCCESS" == resJson.xml.return_code && "SUCCESS" == resJson.xml.result_code){
      var nostr = new Date().getTime() / 1000 * 719759154 + "";
      var pck = 'prepay_id=' + resJson.xml.prepay_id;
      var time = Math.floor(new Date().getTime() / 1000);
      var clientSign = await wxSign(apiConfig.wx.sub_appid,pck,time,nostr,'MD5');
      var ret = {
          code : "SUCCESS",
          prepayid : resJson.xml.prepay_id,
          orderNum : orderNum,
          sign : clientSign,
          nonceStr : nostr,
          pck : pck,
          timestamp : time,
          appId : apiConfig.wx.sub_appid
      }
      console.log(ret);
      return JSON.stringify(ret);
    }else{
      var ret = {
          code : "FAIL",
          msg : resJson.xml.return_msg
      }
      return JSON.stringify(ret);
    }
  }else{
    var ret = {
        code : "FAIL",
        msg : "REQUEST INVAILD"
    }
    return JSON.stringify(ret);
  }
}

let prePayRequest =  async (orderName,orderNum,price,wxPayType,clientIP,pf,attach,openid) => {
  return new Promise(function (resolve, reject){
    try{
      let nonestr =  new Date().getTime();
      let appId = apiConfig.wx.appId;
      let mchId = apiConfig.wx.mchId;
      let sub_appId = apiConfig.wx.sub_appId;
      let sub_mchId = apiConfig.wx.sub_mchId;
      let notifyUrl = apiConfig.wx.notifyUrl;
      let sign = prepaySign(appId,mchId,sub_appId,sub_mchId,nonestr,orderName,orderNum,price,clientIP,notifyUrl,wxPayType,attach,openid);
      console.log("sign:" + sign);
      let formData = "<xml>";
      formData += "<appid>"+ appId +"</appid>";
      formData += "<mch_id>"+ mchId +"</mch_id>";
      formData += "<sub_appid>"+ sub_appId +"</sub_appid>";
      formData += "<sub_mch_id>"+ sub_mchId +"</sub_mch_id>";
      formData += "<nonce_str>"+ nonestr +"</nonce_str>";
      formData += "<sign>"+ sign +"</sign>";
      formData += "<body>"+ orderName +"</body>";
      formData += "<notify_url>"+ notifyUrl +"</notify_url>";
      formData += "<out_trade_no>"+ orderNum +"</out_trade_no>";
      formData += "<spbill_create_ip>"+ clientIP +"</spbill_create_ip>";
      formData += "<total_fee>"+ price +"</total_fee>";
      formData += "<trade_type>"+ wxPayType +"</trade_type>";
      formData += "<attach>"+ attach +"</attach>";
      formData += "<openid>"+ openid +"</openid>";
      formData += "<sub_openid>"+ openid +"</sub_openid>";
      formData += "</xml>";
      console.log("请求参数:" + formData);
      request({url:apiConfig.wx.unifiedOrder,method:'POST',body:formData},function(err,response,body){
        let data = {
          err : err,
          response: response,
          body :body
        };
        console.log(body);
        resolve(data);
      });
    }catch(e){
      //TODO handle the exception
      var ret = {
          code : "FAIL",
          msg : "PAY FAIL" + e.name + ":" + e.message
      }
      resolve(ret);
    }
  });
}

exports.prePay =  async (orderName,orderNum,price,wxPayType,clientIP,pf,attach,openid) => {
  //openid = "ovOSCwkGCf_YUjth3aiLdkxAmiPI";
	var ret = await prePayRequest(orderName,orderNum,price,wxPayType,clientIP,pf,attach,openid);
  console.log(ret);
	if (ret.code == "FAIL"){
		return ret;
	}else{
		return await parseBody(ret.err,ret.response,ret.body,pf,orderNum);
	}
}

exports.getSignByNotify = async (args) => {
	var keys = Object.keys(args);
	 keys = keys.sort()
		  var newArgs = {};
		  keys.forEach(function (key) {
		  	if(key != "sign"){
		  		newArgs[key] = args[key];
		  	}
		  });

		  var string = '';
		  for (var k in newArgs) {
		    string += '&' + k + '=' + newArgs[k];
		  }
    string = string.substr(1);
    string = string + '&key=' + apiConfig.wx.key;
    console.log("签名串:" + string);
	return security.md5(string).toUpperCase();
}
